<?php

use Firebase\JWT\JWT;

/**
 * curl_get请求
 * $url 请求地址
 */
function curlGet($url, $type = 1)
{
    $header = array(
        'Accept: application/json',
    );
    $curl = curl_init();
    // 设置请求头
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    curl_setopt($curl, CURLOPT_TIMEOUT, 5000);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($curl, CURLOPT_URL, $url);
    if ($type == 1) {
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    }
    $res = curl_exec($curl);
    if ($res) {
        curl_close($curl);
        return $res;
    } else {
        $error = curl_errno($curl);
        curl_close($curl);
        return $error;
    }
}

/**
 * curl_post 请求
 * $url 请求链接
 * $postdata 请求数据
 * $type：1.array，2.json
 */
function curlPost($url, $postdata = [], $type = 1)
{
    $header = array(
        'Accept: application/json',
    );
    //初始化
    $curl = curl_init();
    //设置抓取的url
    curl_setopt($curl, CURLOPT_URL, $url);
    //设置头文件的信息作为数据流输出
    curl_setopt($curl, CURLOPT_HEADER, 0);
    //设置获取的信息以文件流的形式返回，而不是直接输出。
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    // 超时设置
    curl_setopt($curl, CURLOPT_TIMEOUT, 10);

    // 超时设置，以毫秒为单位
    // curl_setopt($curl, CURLOPT_TIMEOUT_MS, 500);

    // 设置请求头
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);

    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

    //设置post方式提交
    curl_setopt($curl, CURLOPT_POST, 1);
    if ($type == 1) {
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
    } else {
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($postdata));
    }
    //执行命令
    $data = curl_exec($curl);

    // 显示错误信息
    if (curl_error($curl)) {
        curl_close($curl);
        return "Error: " . curl_error($curl);
    } else {
        // 打印返回的内容
        curl_close($curl);
        return json_decode($data, true);

    }
}

/**
 * 成功返回信息
 * status：状态码
 * msg：提示信息
 * data：返回数据
 */
function sucessMsg($status = 200, $msg = '获取成功！', $data = [])
{
    return json([
        'code' => $status,
        'msg' => $msg,
        'data' => $data
    ], 200);
}

/**
 * 失败返回信息
 * status：状态码
 * msg：错误信息
 * data：返回数据
 */
function errMsg($status = 500, $msg = '获取失败！', $data = [])
{
    return json([
        'code' => $status,
        'msg' => $msg,
        'data' => $data
    ], 200);
}

/**
 * 返回随机字符串
 * length：字符串长度
 */
function getRandStr($length = 4)
{
    //字符组合
    $str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $len = strlen($str) - 1;
    $randstr = '';
    for ($i = 0; $i < $length; $i++) {
        $num = mt_rand(0, $len);
        $randstr .= $str[$num];
    }
    return $randstr;
}

/**
 * 生成密码
 * $password：密码
 * $salt：加密盐
 */
function makePassword($password, $salt)
{
    return md5(md5($password) . $salt);
}

/**
 * 验证密码
 * $password：密码
 * $salt：加密盐
 * $password_hash：用户密码
 */
function checkPassword($password, $member)
{
    if (empty($password) || empty($member)) {
        return false;
    }
    $inputPassword = makePassword($password, $member->salt);
    if ($inputPassword !== $member->password_hash) {
        return false;
    }
    return true;
}

/**
 * 生成验签
 * $uid 用户id
 * $key 这里是自定义的一个随机字串，应该写在config文件中的，解密时也会用，相当于加密中常用的盐  salt
 */
function signToken($uid, $type = 'api', $key = '!@#$%*&')
{
    $token = array(
        "iss" => $key,        //签发者 可以为空
        "aud" => '',          //面象的用户，可以为空
        "iat" => time(),      //签发时间
        "nbf" => time(),    //在什么时候jwt开始生效  （这里表示生成100秒后才生效）
        "exp" => time() + 43200, //token 过期时间 43200
        "data" => [           //记录的userid的信息，这里是自已添加上去的，如果有其它信息，可以再添加数组的键值对
            'uid' => $uid,
            'login_type' => $type
        ]
    );
    $resToken = JWT::encode($token, $key, "HS256");  //根据参数生成了 token
    return $resToken;
}

/**
 * 验证token
 */
function checkToken($token, $key = '!@#$%*&')
{
    $status = array("code" => -1);
    try {
        JWT::$leeway = 60;//当前时间减去60，把时间留点余地
        $decoded = JWT::decode($token, $key, array('HS256')); //HS256方式，这里要和签发的时候对应
        $arr = (array)$decoded;
        $res['code'] = 0;
        $res['data'] = $arr['data'];
        return $res;

    } catch (\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
        $status['msg'] = "签名不正确";
        return $status;
    } catch (\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
        $status['msg'] = "token未生效";
        return $status;
    } catch (\Firebase\JWT\ExpiredException $e) { // token过期
        $status['msg'] = "token失效,登录已过期";
        return $status;
    } catch (\Exception $e) { //其他错误
        $status['msg'] = "未知错误";
        return $status;
    }
}

/**
 * 获取树结构
 * $arr 必须为数组
 * $pid 父id（上级id），默认为0
 */
function getTree($arr, $pid = 0, $level = 0)
{
    if (!is_array($arr)) {
        return false;
    }
    $tree = [];
    foreach ($arr as $k => $v) {
        if ($v['pid'] == $pid) {
            $tree[$k] = $v;
            $tree[$k]['level'] = $level;
            $tree[$k]['children'] = getTree($arr, $v['id'], $level + 1);
        }
        unset($arr[$k]);
    }
    return array_values($tree);
}


/**
 * 处理树结构改变名称
 * $cateRes 必须为数组
 * $pid 父id（上级id），默认为0
 * $level 等级
 */
function getChild($cateRes, $pid = 0, $level = 0)
{
    static $arr = [];
    foreach ($cateRes as $k => $v) {
        if ($v['pid'] == $pid) {
            // $v['level'] = $level;
            if ($level != 0) {
                $v['name'] = '|' . str_repeat('--', $level) . $v['name'];
            }
            $arr[] = $v;
            getChild($cateRes, $v['id'], $level + 1);
        }
    }
    return $arr;
}

function getList($cate, $pid = 0, $level = 0)
{
    $arr = array();
    foreach ($cate as $k => $v) {
        if ($v['pid'] == $pid) {
            $joinStr = $level == 0 ? '' : str_repeat('└― ', $level); //判断是否是第一级分类
            // $v['menu_level'] = $level + 1;
            $v['name'] = $joinStr . $v['name'];
            $arr[] = $v;
            unset($cate[$k]); //删除该节点，减少递归的消耗
            $arr = array_merge($arr, getList($cate, $v['id'], $level + 1));
        }
    }
    return $arr;
}

function listComment($comment, $pid = 0, $level = 0)
{
    $arr = array();
    foreach ($comment as $k => $v) {
        if ($v['pid'] == $pid) {
            $joinStr = $level == 0 ? '' : str_repeat('└― ', $level); //判断是否是第一级评论
            // $v['menu_level'] = $level + 1;
            $v['comment'] = $joinStr . $v['comment'];
            $arr[] = $v;
            unset($comment[$k]); //删除该节点，减少递归的消耗
            $arr = array_merge($arr, listComment($comment, $v['id'], $level + 1));
        }
    }
    return $arr;
}

/**
 * @desc    设置cookie浏览记录
 */
function set_cookie_history($search)
{
    //设置初始数据
    $set_limit = 5; //浏览记录的容量限制
    //获取cookie记录
    $history_array = unserialize(\think\facade\Request::cookie('cookie_history'));
    if (!$history_array)
        $history_array = [];
    //浏览记录存在
    if (in_array($search, $history_array)) {
        unset($history_array[array_search($search, $history_array)]); //删除存在
        array_unshift($history_array, $search);//重新放在第一个
        //浏览记录不存在
    } else {
        //没有超过记录的容量限制，直接放在第一个
        if (count($history_array) < $set_limit) {
            array_unshift($history_array, $search);
            //超过记录的容量限制，删除最后一个，然后放在第一个
        } else {
            array_pop($history_array);
            array_unshift($history_array, $search);
        }
    }
    $expire_time = 3600 * 24 * 30; //过期时间
    //$cookie_domain = config('domain');
    //将浏览数组序列化后写入cookie
    $history_array = serialize($history_array);
    //setcookie('cookie_history', $history_array, time()+$expire_time, '/', $cookie_domain);
    setcookie('cookie_history', $history_array, time() + $expire_time);
}

/**
 * @desc    获取cookie浏览记录
 */
function get_cookie_history()
{
    //设置初始返回数据
    $return_data = [];
    //获取cookie记录
    $history_array = unserialize(\think\facade\Request::cookie('cookie_history'));
    if ($history_array)
        return $history_array;
    //非法获取数据，直接返回
    return $return_data;
}

function set_history($data)
{
    $hist = unserialize(\think\facade\Request::cookie('history'));
    if (!$hist) {
        $hist = [];
    }
    if (in_array($data, $hist)) {
        unset($hist[array_search($data, $hist)]);
        array_unshift($hist, $data); //向数组第一个加元素
    }
    if (count($hist) > 4) {
        array_pop($hist);
        array_unshift($hist, $data); //向数组第一个加元素
    } else {
        array_unshift($hist, $data); //向数组第一个加元素
    }
    setcookie('history', serialize($hist), time() + 3600 * 24 * 30);
}

function get_history()
{
    $hist = \think\facade\Cookie::get('history');
    if (!$hist) {
        return [];
    }
    return unserialize($hist);
}


/*
 * 转变时间格式
 * */
function formatTime($time)
{
    $time = strtotime($time);
    $now_time = time();
    $t = $now_time - $time;

    $year = (int)($t / (86400 * 30 * 12));
    if ($year >= 1) {
        return $year . '年前';
    }
    $mon = (int)($t / (86400 * 30));
    if ($mon >= 1) {
        return $mon . '月前';
    }
    $day = (int)($t / 86400);
    if ($day >= 1) {
        return $day . '天前';
    }
    $h = (int)($t / 3600);
    if ($h >= 1) {
        return $h . '小时前';
    }
    $min = (int)($t / 60);
    if ($min >= 1) {
        return $min . '分钟前';
    }
    return '刚刚';
}

/*
 * 转变时间格式
 * */

function changeTime($data, $str)
{
    foreach ($data as &$v) {
        $v[$str] = formatTime($v[$str]);
        unset($v);
    }
    return $data;
}

/*
 * 给图片路径拼装域名
 * */
function changeImage($data, $str)
{
    foreach ($data as &$v) {
        $v[$str] = env('APP.YUMING') . $v[$str];
        unset($v);
    }
    return $data;
}


/*
 * 详情里面删除html标签
 * */
function delHtml($data, $str)
{
    foreach ($data as &$v) {
        $v[$str] = str_replace("&nbsp;", "", $v[$str]);//去掉空格
        $v[$str] = strip_tags($v[$str]);//函数剥去字符串中的 HTML、XML 以及 PHP 的标签,获取纯文本内容
    }
    return $data;
}

/*
 * 生成验证码并设置session
 * */

function setCode()
{
    $code = getRandStr();
    $forwarded = request()->header("x-forwarded-for");
    if ($forwarded) {
        $ip = explode(',', $forwarded)[0];
    } else {
        $ip = request()->ip();

    }
    $name = 'code:' . str_replace('.', '', $ip);
    session($name, $code, time() + 300);
    return $code;
}


/*
 * 比对code 并删除session
 * */

function getCode($code)
{
    $forwarded = request()->header("x-forwarded-for");
    if ($forwarded) {
        $ip = explode(',', $forwarded)[0];
    } else {
        $ip = request()->ip();
    }
    $session_name = 'code:' . str_replace('.', '', $ip);
    $session_code = session($session_name);

    if (!$session_code) {
        return 401;
    }
    if (strlen($code) != 6 || strncasecmp($code, $session_code, 6)) {
        return 402;
    }
    return $session_name;
}

/*
 * 获取文件大小
 * */

function trans_byte($byte)
{

    $KB = 1024;

    $MB = 1024 * $KB;

    $GB = 1024 * $MB;

    $TB = 1024 * $GB;

    if ($byte < $KB) {

        return $byte . "B";

    } elseif ($byte < $MB) {

        return round($byte / $KB, 2) . "KB";

    } elseif ($byte < $GB) {

        return round($byte / $MB, 2) . "MB";

    } elseif ($byte < $TB) {

        return round($byte / $GB, 2) . "GB";

    } else {

        return round($byte / $TB, 2) . "TB";

    }

}

/*
 * 获取两个字符之间的字符串
 * */

function getSub($lei, $start, $end)
{

    $result = substr($lei, strripos($lei, "$start") + 1);
    $result = substr($result, 0, strrpos($result, "$end"));

    return $result;
}
